package payment

import (
	"fmt"
	"net/http"
)

var FormTpl = `<html>
<meta http-equiv=Content-Type content="text/html;charset=utf-8">
<style>.loader {margin-bottom:20px;border:15px solid #f3f3f3;border-radius:50%%;border-top:15px solid #3498db;width:40px;height:40px;-webkit-animation:spin 2s linear infinite;animation:spin 2s linear infinite;margin: 0 auto}@-webkit-keyframes spin{0%%{-webkit-transform:rotate(0deg)}100%%{-webkit-transform:rotate(360deg)}}@keyframes spin{0%%{transform:rotate(0deg)}100%%{transform:rotate(360deg)}}</style>
<body style="width:100%%;min-height:500px;background-color:#FFF;padding-top:200px;">
<div style="border: dashed 1px #9E9C9C; text-align:  center; width: 40%%; margin: 0 auto;color:#666666;padding-bottom:20px;">
<h1 style="color:#70ca63">提交订单成功</h1>
<h5 style="margin-bottom:20px;">正在跳转到支付商...</h5>
<div class="loader"></div>
</div>
%s
</body>
<script>document.forms['pay'].submit();</script>
</html>`

const (
	JSON           string = "JSON"
	STRING         string = "STRING"
	XML            string = "XML"
	HTTPSTATUSCODE string = "HTTPSTATUSCODE"
)

type PayApi struct {
	ReqUri string
	Mid    string
	Key    string
	Secret string
	Code   string
	Param  string
}

type PayClient interface {
	Pay(*Charge) (*PayInfo, error)                 // 實作第三方支付請求
	VerifySign(*http.Request) (*BaseResult, error) // 接收第三方回調及後續處理
	Notify(*BaseResult) *BaseNotify                // 實作返回給第三方的訊息

	Withdrawal(*Charge, *Withdrawal) (*BaseResult, error)
	WithdrawalSign(*http.Request) (*BaseResult, error)
}

type Charge struct {
	ApiUrl    string  //api URL
	OrderSn   string  // 订单号
	Money     float64 //金额
	NotifyURL string  //通知
	BackURL   string  //返回
	Type      string  //支付方式
	Ip        string
	Mobile    bool
	Time      string
	GameCode  string // 游戏编号
	PartnerId string // 商户号
	UserId    int    // 用戶id
	Lang      string // 語系資料 (ISO 639-1 code)
	Email     string // user email
	FirstName string // user 名
	LastName  string // user 姓
	Username  string // user 姓名
}

type Withdrawal struct {
	BankCode string //银行编号
	BankName string ////银行名称
	Name     string //用户名字
	Card     string //银行卡号
	Province string //开户省
	City     string //开户市
	Branch   string
}

type PayInfo struct {
	Type    string //  qr, app, html, form
	Content string
	ThirdSn string
}

// BaseResult 支付结果
type BaseResult struct {
	IsSucceed  bool   // 是否交易成功
	OrderSn    string // 内部交易流水号
	ExternalSn string // 对外交易流水号
	ThirdSn    string // 第三方生成流水号
	Params     string //第三方回来的参数
	Mobile     bool
	Money      float64
	FixMoney   bool // 訂單是否以三方回調金額為主
	Status     int  //0 等待，1完成，2失败
	IsManual   int  //第三方或四方為手動處理
}

type BaseNotify struct {
	Type           string
	Ret            interface{}
	HttpStatusCode int
}

type InitPayClient func(PayApi) (PayClient, error)

type pay struct {
	client string
	initer InitPayClient
}

var pays map[string]*pay

func init() {
	pays = make(map[string]*pay)
}

func RegisterPay(name string, initFn InitPayClient) error {
	_, existing := pays[name]
	if existing {
		return fmt.Errorf("pays with name '%s' is already registered", name)
	}
	pays[name] = &pay{
		client: name,
		initer: initFn,
	}
	return nil
}

func GetPayClient(api PayApi) (PayClient, error) {
	fName := "GetPayClient"
	pay, exists := pays[api.Code]
	if !exists {
		return nil, fmt.Errorf("pays with name '%s' is not registered", api.Code)
	}
	client, err := pay.initer(api)
	if err != nil {
		return nil, fmt.Errorf("%s%s", fName, err.Error())
	}
	return client, nil
}
